{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# TVM 宏\n",
    "源码：`tvm/include/tvm/runtime/c_runtime_api.h`\n",
    "```c++\n",
    "// Macros to do weak linking\n",
    "#ifdef _MSC_VER\n",
    "#define TVM_WEAK __declspec(selectany)\n",
    "#else\n",
    "#define TVM_WEAK __attribute__((weak))\n",
    "#endif\n",
    "\n",
    "#ifdef __EMSCRIPTEN__\n",
    "#include <emscripten/emscripten.h>\n",
    "#define TVM_DLL EMSCRIPTEN_KEEPALIVE\n",
    "#endif\n",
    "\n",
    "// helper macro to suppress unused warning\n",
    "#if defined(__GNUC__)\n",
    "#define TVM_ATTRIBUTE_UNUSED __attribute__((unused))\n",
    "#else\n",
    "#define TVM_ATTRIBUTE_UNUSED\n",
    "#endif\n",
    "\n",
    "#ifndef TVM_DLL\n",
    "#ifdef _WIN32\n",
    "#ifdef TVM_EXPORTS\n",
    "#define TVM_DLL __declspec(dllexport)\n",
    "#else\n",
    "#define TVM_DLL __declspec(dllimport)\n",
    "#endif\n",
    "#else\n",
    "#define TVM_DLL __attribute__((visibility(\"default\")))\n",
    "#endif\n",
    "#endif\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这段代码主要是为了实现弱链接和动态库的导出。\n",
    "\n",
    "1. 首先，它定义了宏 `TVM_WEAK`，用于实现弱链接。在 Windows 平台上，使用 `__declspec(selectany)` 可以实现弱链接；在其他平台上，使用 `__attribute__((weak))` 也可以实现弱链接。\n",
    "2. 然后，它检查是否定义了 `__EMSCRIPTEN__`。如果定义了，那么它会包含 `<emscripten/emscripten.h>` 头文件，并定义宏 `TVM_DLL`，值为 `EMSCRIPTEN_KEEPALIVE`。这个宏用于告诉 Emscripten 在生成的 JavaScript 代码中保留这个函数或变量，以便在运行时可以访问到。\n",
    "3. 接下来，它定义了宏 `TVM_ATTRIBUTE_UNUSED`，用于抑制未使用的警告。在 GCC 编译器下，使用 `__attribute__((unused))` 可以实现这个功能；在其他编译器下，这个宏没有定义。\n",
    "4. 最后，它检查是否定义了 `TVM_DLL`。如果没有定义，那么它会再次检查是否定义了 `_WIN32`。如果定义了 `_WIN32`，那么它会检查是否定义了 `TVM_EXPORTS`。如果定义了 `TVM_EXPORTS`，那么它会定义宏 `TVM_DLL`，值为 `__declspec(dllexport)`；否则，它会定义宏 `TVM_DLL`，值为 `__declspec(dllimport)`。如果 `_WIN32` 没有定义，那么它会定义宏 `TVM_DLL`，值为 `__attribute__((visibility(\"default\")))`。"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
